#include "../include/StringUtils.hpp"
#include <iostream>
#include <cassert>

void testConstruction() {
    std::cout << "=== Testing Construction ===" << std::endl;
    
    Utils::StringUtils s1;
    assert(s1.isEmpty());
    assert(s1.length() == 0);
    
    Utils::StringUtils s2("Hello");
    assert(!s2.isEmpty());
    assert(s2.length() == 5);
    assert(s2.toString() == "Hello");
    
    Utils::StringUtils s3(s2);
    assert(s3 == s2);
    
    Utils::StringUtils s4 = "World";
    assert(s4.toString() == "World");
    
    s4 = s2;
    assert(s4 == s2);
    
    std::cout << "All construction tests passed!\n" << std::endl;
}

void testComparison() {
    std::cout << "=== Testing Comparison ===" << std::endl;
    
    Utils::StringUtils s1("apple");
    Utils::StringUtils s2("banana");
    Utils::StringUtils s3("apple");
    
    assert(s1 == s3);
    assert(s1 != s2);
    assert(s1 < s2);
    assert(s2 > s1);
    assert(s1 <= s3);
    assert(s1 >= s3);
    
    std::cout << "All comparison tests passed!\n" << std::endl;
}

void testSearchAndReplace() {
    std::cout << "=== Testing Search and Replace ===" << std::endl;
    
    Utils::StringUtils s("Hello World Hello");
    
    assert(s.indexOf("World") == 6);
    assert(s.lastIndexOf("Hello") == 12);
    assert(s.contains("World"));
    assert(s.count("Hello") == 2);
    
    s.replace("Hello", "Hi");
    assert(s == "Hi World Hi");
    
    Utils::StringUtils s2 = s.replaced("Hi", "Hello");
    assert(s2 == "Hello World Hello");
    
    std::cout << "All search and replace tests passed!\n" << std::endl;
}

void testSubstring() {
    std::cout << "=== Testing Substring ===" << std::endl;
    
    Utils::StringUtils s("Hello World");
    
    assert(s.left(5) == "Hello");
    assert(s.right(5) == "World");
    assert(s.mid(6, 5) == "World");
    assert(s.section(" ", 0, 1) == "Hello World");
    
    auto parts = s.split(" ");
    assert(parts.size() == 2);
    assert(parts[0] == "Hello");
    assert(parts[1] == "World");
    
    Utils::StringUtils joined = Utils::StringUtils::join(parts, "-");
    assert(joined == "Hello-World");
    
    std::cout << "All substring tests passed!\n" << std::endl;
}

void testCaseConversion() {
    std::cout << "=== Testing Case Conversion ===" << std::endl;
    
    Utils::StringUtils s("Hello World");
    
    assert(s.toLower() == "hello world");
    assert(s.toUpper() == "HELLO WORLD");
    assert(s.isLower() == false);
    assert(s.isUpper() == false);
    
    Utils::StringUtils lower("hello");
    assert(lower.isLower());
    
    Utils::StringUtils upper("HELLO");
    assert(upper.isUpper());
    
    std::cout << "All case conversion tests passed!\n" << std::endl;
}

void testNumberConversion() {
    std::cout << "=== Testing Number Conversion ===" << std::endl;
    
    Utils::StringUtils num1 = Utils::StringUtils::number(123);
    assert(num1 == "123");
    
    Utils::StringUtils num2 = Utils::StringUtils::number(3.14159, 'f', 4);
    assert(num2 == "3.1416");
    
    Utils::StringUtils num3("42");
    assert(num3.toInt() == 42);
    
    Utils::StringUtils num4("3.14");
    assert(num4.toDouble() == 3.14);
    
    bool ok = false;
    Utils::StringUtils num5("abc");
    num5.toInt(&ok);
    assert(!ok);
    
    std::cout << "All number conversion tests passed!\n" << std::endl;
}

void testFormatting() {
    std::cout << "=== Testing Formatting ===" << std::endl;
    
    Utils::StringUtils s("The answer is %1, not %2");
    s.arg(42).arg(43);
    assert(s == "The answer is 42, not 43");
    
    Utils::StringUtils s2("Name: %1, Age: %2");
    s2.arg("John").arg(30);
    assert(s2 == "Name: John, Age: 30");
    
    Utils::StringUtils s3("Number: %1");
    s3.arg(123, 5, '0');
    assert(s3 == "Number: 00123");
    
    std::cout << "All formatting tests passed!\n" << std::endl;
}

void testPaddingAndTrimming() {
    std::cout << "=== Testing Padding and Trimming ===" << std::endl;
    
    Utils::StringUtils s("  hello  ");
    s.trimmed();
    assert(s == "hello");
    
    Utils::StringUtils s2("hello");
    s2.leftJustified(10, '-');
    assert(s2 == "hello-----");
    
    Utils::StringUtils s3("hello");
    s3.rightJustified(10, '-');
    assert(s3 == "-----hello");
    
    Utils::StringUtils s4("  hello  world  ");
    s4.simplified();
    assert(s4 == "hello world");
    
    std::cout << "All padding and trimming tests passed!\n" << std::endl;
}

int main() {
    testConstruction();
    testComparison();
    testSearchAndReplace();
    testSubstring();
    testCaseConversion();
    testNumberConversion();
    testFormatting();
    testPaddingAndTrimming();
    
    std::cout << "=== All StringUtils tests passed! ===" << std::endl;
    return 0;
}